{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n",
" Si c'est votre première visite dans ce TP, lisez attentivement chacun des points détaillé après ce paragraphe.
\n",
" Si vous avez déjà commencer à travailler sur ce TP et que vous souhaiter vous déplacer rapidement dans une partie précise vous pouvez choisir la partie que vous souhaitez rejoindre ci-dessous.
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
\n",
" La technologie jupyter permet d'exécuter du code python par un simple clique sur Executer ci-dessus.
\n",
" Les morceaux de code de cette page sont interprétées case par case. Pour savoir quelle case a été interprétée avant une autre, il suffit de repérer le numéro devant la case.
\n",
" Une fois qu'une case a été interprétée (=exécutée), la page garde en mémoire les variables et fonctions lues
\n",
" La plateforme propose quelques outils de purge de la mémoire : \n",
"
\n",
" Pour ne pas perdre votre travail pensez à le sauvegarder régulièrement. Par défault, la sauvegarde par un clic sur la disquette en haut à gauche de page, ou par le racourci clavier classique ctrl+S
\n",
" est une sauvegarde en local, sur le serveur de jupyter. Vous pouvez et devez très régulièrement sauvegarder votre travail sur votre support personnel de sauvegarde (clef USB, se l'envoyer par mail etc). Ce faisant vous disposerez d'un fichier .ipynb (IPYthon NoteBook) qu'il vous suffira de recharger pour avancer. Après le rechargement assurez vous que les fonctionnalités anciennement developpées et variables utilisées sont bien dans la mémoire de la page (en rééxecutant les cases, ou plus rapidement par Kernel > Restart & Run All.
A NOTER : vous pouvez travailler sur le tp (et tout autre fichier .ipynb) hors connexion en installant une version local du notebook de jupyter. Il faut que votre machine possède un interpreteur de python et que vous soyez connecter à internet.\n", "
pip install jupyterlab
jupyter notebook
Comme pour le TP1 et le TP2, une bibliothèque regroupant quelques outils de la cryptologie vous ont été donnée. Chargeons l'intégralité des fonctionnalités qu'elle propose
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from OutilsCrypto import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vous êtes invité à travailler sur la première partie du TP1 pour vous refamiliariser avec les fonctionnalités de cette bibliothèque comme codex
, codex
, xedoc
, paquet
, mode2base
, Filtre
ainsi que les fonctions d'attaque par dictionnaire.
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
Pour vous aider lors de la réalisation de ce TP et des tests de validités, plusieurs fonctionnalité vous ont été donnée. L'objectif de cette partie est de les explorer
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "printM(M)
Inforamatiquement une matrice sera considéré comme un tableau à deux entrées. Le premier indice correspondera toujours à la ligne tandis que le second à la colonne. On prendra garde, les tableaux sont informatiquement numéroté : le premier indice (ligne ou colonne) a le numéro 0. Par exemple si A
est une matrice alors A[0][1]
représente la valeur à l'intersection de la première ligne et de la seconde colonne
La procédure printM
affiche la matrice passée en paramètre.
prodMat(A,B)
Cette fonction renvoie le résultat du produit matriciel $A\\times B$. En ca d'impossibilité la matrice vide (tableau vide) est renvoyé.
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"N*M =\")\n", "printM( prodMat(N, M) )\n", "print(\"M*N =\")\n", "printM( prodMat(M, N) )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
Reprennez du TP2, la fonction PGCD
qui prend en paramètre deux entiers a
et b
et qui renvoie le plus grand diviseur commun à ces deux nombres.
Reprennez du TP2, la fonction inv_mod
qui prend en paramètre deux entiers a
et n
et renvoie l'inverse de a
modulo n
. On convient que lorsque c'est impossible, la fonction renvoie $0$
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
Dans cette partie, comme vu en cours et en TD, nous nous intérèsserons uniquement à l'application du cryptosystème de Hill en dimension 2, c'est à dire que nous ne considèrerons que des matrices à 2 lignes et deux colonnes.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Ecrire la fonction detDim2
qui prend en paramètre une matrice A
et renvoie son déterminant (en suivant simplement ce que nous avions nomé dans le cours la règle du gamma)
Ecrire la fonction inv_mat_modDim2(A, n)
qui renvoie l'inverse d'une matrice A
(toujours en dimension 2 - en appliquant donc simplement la formule vu en cours) modulo n
. En cas d'impoibilité, on renvoie la matrice vide (tableau vide)
Ecrire la fonction EHillDim2
qui renvoie le chiffrement de Hill. La fonction renvoie la chaine vide en cas d'erreur.
Ecrire la fonction DHillDim2
qui renvoie le déchiffrement de Hill. La fonction renvoie la chaine vide en cas d'erreur.
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
La fonction suivante, incrémente la matrice A
modulairement (mod
). Si suite à cet incrément on trouve la matrice nulle on renvoie à la place la matrice vide (tableau vide)
Comme pour les TP1 et TP2, rédiger une fonction d'attaque en force brute, utlisant la recherche par dictionnnaire
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"-----> DéBUT DU CHARGMENT DES DICTIONNAIRES <-----\")\n", "top=time.time()\n", "lang=\"FR\"\n", "print(\"CHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tEN COURS\",end='')\n", "DICO_FR = MonDico(lang)\n", "print(\"\\rCHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tTERMINéE (en\", round(time.time()-top, 3), \"secondes)\")\n", "top=time.time()\n", "lang=\"ANG\"\n", "print(\"CHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tEN COURS\",end='')\n", "DICO_ANG = MonDico(lang)\n", "print(\"\\rCHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tTERMINéE (en\", round(time.time()-top, 3), \"secondes)\")\n", "top=time.time()\n", "lang=\"ESP\"\n", "print(\"CHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tEN COURS\",end='')\n", "DICO_ESP = MonDico(lang)\n", "print(\"\\rCHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tTERMINéE (en\", round(time.time()-top, 3), \"secondes)\")\n", "top=time.time()\n", "lang=\"IT\"\n", "print(\"CHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tEN COURS\",end='')\n", "DICO_IT = MonDico(lang)\n", "print(\"\\rCHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tTERMINéE (en\", round(time.time()-top, 3), \"secondes)\")\n", "print(\"-----> FIN DU CHARGMENT DES DICTIONNAIRES <-----\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def bruteforceHill_dico(txt, paq=1, dico=DICO_FR) : \n", " try : \n", " txt=str(txt)\n", " paq=int(paq)\n", " except :\n", " print(\"L'attaque ne fonctionne pas\")\n", " return\n", "\n", " print(\"---------------------------------------------------\")\n", " print(\"Début de l'attaque en force brute avec dictionnaire\")\n", " print(\"---------------------------------------------------\")\n", " \n", " top=time.time()\n", " \n", " #Mettre votre code ici\n", " \n", " temps=time.time()-top\n", " print(\"Le dernier message semble être le bon\")\n", " print(\"Attaque terminée (\"+str(round(temps, 3))+\"s)\")\n", " print(\"---------------------------------\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
det
et inv_mat_mod
Comme en dimension $2$, il existe des formule bien connue permettant de calculer le determinant de n'importe quelle matrice carré ainsi que son inverse (lorsque son déterminant est inversible). Ce n'est pas l'objectif de ce cours que d'introduie ces notion : elles sont gratuites !\n", "
det(A)
renvoie le déterminant de n'importe quelle matrice carréinv_mat_mod(A, d1, n)
renvoie la matrice inverse de A
modulo n
. Le nombre d1
représente l'inverse modulaire du déterminant de A
modulo n
En adaptant votre code en dimension 2, écrire les fonctions EHill
et DHill
de déchiffrement quelque soit la dimension de la matrice clef.
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
On renvoie au cours pour comprendre le principe des associations et les constructions vectoriels qui se déduisent du claire connu ($\\rightarrow$ ici (bas de page)).\n",
"
\n",
" Le principe est donc d'associer les informations vectoriellement pour obtenir des équations de la forme $AU=V$ où $U$ est une partie claire du message, $V$ une partie crypté du message et $A$ la clef inconnue que nous cherchons à casser. La difficulté de cette attaque est purement algorithmique : il faut créer tous les $U$ et $V$ possible pour obtenir une matrice inversible permettant de trouver $A=VU^{-1}$. A cette fin, nous vous proposons la fonction lst_ss_ens(E, p)
qui est un tableau regroupant tous les sous-ensembles (sous tableau) de cardinalité $p$ que l'on peut faire avec le tableau $E$.\n",
"
Ecrire la fonction AttaqueAClaireConnu
qui réalise une attaque à claire connue. Quelques petite aides vous sont soufflé.
\n",
"A propos des paramètres : \n",
"
crypte
est le message cryptéclaire
est le message clairepos
est la position du texte clairedim
est la dimension hypothétique de la clef